<template>
  <view class="flex-center">
    <!-- 触发slot，点击弹出选择器 -->
    <view @click="showPicker = true">
      <slot>
        <nut-button
          type="primary"
          class="w-[320rpx] rounded-2xl text-[28rpx] bg-[#165DFF]"
        >
          {{ displayText || '请选择省市' }}
        </nut-button>
      </slot>
    </view>
    <!-- nut-picker 弹窗 -->
    <nut-popup v-model:visible="showPicker" position="bottom" round>
      <nut-picker
        :columns="[provinceOptions, cityOptions]"
        :default-index="defaultIndexes"
        title="选择省市"
        @confirm="onConfirm"
        @change="onChange"
        @cancel="showPicker = false"
      />
    </nut-popup>
  </view>
</template>

<script setup lang="ts">
import { ref, watch, computed, onMounted } from 'vue'
import { post } from '@/utils/request'
import { showToast } from '@tarojs/taro'
import type { PropType } from 'vue'

/**
 * 省市选择组件
 * @description 先获取省列表，选省后根据省id获取市列表，选择后emit到父组件，支持prop默认值。
 * @performance 只在必要时请求数据，避免重复请求。
 */

interface RegionOption {
  text: string
  value: string | number
}

const props = defineProps({
  /**
   * 默认值 [省id, 市id]
   */
  modelValue: {
    type: Array as unknown as PropType<[string | number, string | number]>,
    default: () => ['', '']
  }
})

const emit = defineEmits<{
  (e: 'update:modelValue', val: [string | number, string | number]): void
  (e: 'change', val: { province: RegionOption; city: RegionOption }): void
}>()

const showPicker = ref(false)
const provinceOptions = ref<RegionOption[]>([])
const cityOptions = ref<RegionOption[]>([])
const selectedProvince = ref<RegionOption | null>(null)
const selectedCity = ref<RegionOption | null>(null)

// 默认索引
const defaultIndexes = computed(() => {
  const provinceIdx = provinceOptions.value.findIndex(p => p.value == props.modelValue[0])
  const cityIdx = cityOptions.value.findIndex(c => c.value == props.modelValue[1])
  return [provinceIdx >= 0 ? provinceIdx : 0, cityIdx >= 0 ? cityIdx : 0]
})

// 显示文本
const displayText = computed(() => {
  if (selectedProvince.value && selectedCity.value) {
    return selectedProvince.value.text + ' ' + selectedCity.value.text
  }
  return ''
})

/**
 * 获取省份列表
 */
const fetchProvinces = async () => {
  try {
    const res = await post('/dictionary/region', { fatherId: 7459 })
    console.log("region===", res)
    if (res.code === 0 && Array.isArray(res.data)) {
      provinceOptions.value = res.data.map((item: any) => ({
        text: item.columns.REGION_NAME,
        value: item.columns.ID
      }))
    } else {
      showToast({ title: res.message || '获取省份失败', icon: 'none' })
    }
  } catch (err) {
    showToast({ title: '获取省份失败', icon: 'none' })
  }
}

/**
 * 获取市列表
 * @param provinceId 省id
 */
const fetchCities = async (provinceId: string | number) => {
  try {
    const res = await post('/dictionary/region', { fatherId: provinceId })
    if (res.code === 0 && Array.isArray(res.data)) {
      cityOptions.value = res.data.map((item: any) => ({
        text: item.columns.REGION_NAME,
        value: item.columns.ID
      }))
    } else {
      cityOptions.value = []
      showToast({ title: res.message || '获取城市失败', icon: 'none' })
    }
  } catch (err) {
    cityOptions.value = []
    showToast({ title: '获取城市失败', icon: 'none' })
  }
}

/**
 * 选择变化时
 */
const onChange = async (params: { selectedValue: (string | number)[]; selectedOptions: RegionOption[] }) => {
  const [province, city] = params.selectedOptions
  if (province && province.value !== selectedProvince.value?.value) {
    selectedProvince.value = province
    await fetchCities(province.value)
    // 选省后重置市
    selectedCity.value = cityOptions.value[0] || null
  } else if (city) {
    selectedCity.value = city
  }
}

/**
 * 确认选择
 */
const onConfirm = (params: { selectedValue: (string | number)[]; selectedOptions: RegionOption[] }) => {
  const [province, city] = params.selectedOptions
  selectedProvince.value = province
  selectedCity.value = city
  showPicker.value = false
  emit('update:modelValue', [province?.value, city?.value])
  emit('change', { province, city })
}

// 初始化加载省份和默认市
onMounted(async () => {
  await fetchProvinces()
  // 如果有默认省id
  if (props.modelValue[0]) {
    const province = provinceOptions.value.find(p => p.value == props.modelValue[0])
    if (province) {
      selectedProvince.value = province
      await fetchCities(province.value)
      // 如果有默认市id
      if (props.modelValue[1]) {
        const city = cityOptions.value.find(c => c.value == props.modelValue[1])
        if (city) selectedCity.value = city
      }
    }
  }
})

// 监听外部modelValue变化
watch(() => props.modelValue, async (val) => {
  if (val[0] && val[0] !== selectedProvince.value?.value) {
    const province = provinceOptions.value.find(p => p.value == val[0])
    if (province) {
      selectedProvince.value = province
      await fetchCities(province.value)
    }
  }
  if (val[1]) {
    const city = cityOptions.value.find(c => c.value == val[1])
    if (city) selectedCity.value = city
  }
}, { immediate: false })
</script> 